Contents

1 Preamble

1.1 Dependencies

library(ggplot2)
library(patchwork)
library(SpatialData)
library(SingleCellExperiment)

1.2 Introduction

2 SpatialData

The SpatialData class contains 5 layers that are represented as follows:

dir <- file.path("extdata", "raccoon")
dir <- system.file(dir, package="SpatialData", mustWork=TRUE)
(spd <- readSpatialData(dir))
## class: SpatialData
## table: nan 
## images(1): raccoon
## labels(1): segmentation
## shapes(1): circles
## points(0):
## coords(1): global

2.1 Accession

The following accessors are currently supported:

  • image/label/shape/pointNames to retrieve available elements of the respective layer.
  • images/labels/shapes/points to retrieve a list of elements of the respective layer.
  • image/label/shape/point to retrieve a single element of the respective layer.
  • $ to directly access the elements of the respective layer.

SpatialData objects behave like a list, i.e., entities of a all elements can be accessed in various (equivalent) ways:

# these are all equivalent
i <- imageNames(spd)[1]
element(spd, "images", i)
images(spd)[[i]]
image(spd, i)
spd$images[[i]]

2.2 Elements

The ZarrArray class is essentially an Annotated array-like object, that may contain a dense array or any type of Array (e.g., Sparse/DelayedArray). Derived here-from are the ImageArray and LabelArray classes that represent single entities of images and labels, respectively. These differ slightly in their associated metadata and array properties, but share many functions.

# extract 'ImageArray'
img <- image(spd, i)
# rename channels
channels(img) <- c("R", "G", "B")
img
## class: ImageArray
## channels: R G B 
## axiis(cyx): 3 768 1024 
## |-time(0):  
## |-space(2): y x 
## |-channel(1): c 
## coords(1): global

Shapes are represented as ShapeFrames. Currently, these support shapes of type circle and polygon. Under the hood, these are just DataFrames (with specialized methods and additional internal requirements):

(s <- shape(spd))
## class: ShapeFrame
## geoms: 4 
## type: circle 
## coords(1): global
DataFrame(s)
## DataFrame with 4 rows and 4 columns
##          data   index  radius        type
##       <array> <array> <array> <character>
## 1 c(610, 450)       0      30      circle
## 2 c(730, 325)       1      30      circle
## 3 c(575, 300)       2      30      circle
## 4  c(480, 90)       3      50      circle

3 Transformations

Only translation, scaling, and rotation of Image/LabelArrays are currently supported via the following functions, each of which expects a object (SD), as well as transformation data t according to:

Available coordinate systems can be retrieved via coords():

coords(img)
##     input.axes input.name  output.axes output.name     type
## 1 c("c", "....        cyx c("c", "....      global identity

3.1 Translation

# move the raccoon up'n' down
.spd <- spd
images(.spd) <- lapply(
    c(-300, 0, 300), 
    \(t) translateElement(img, c(0, t, 0)))
wrap_plots(lapply(
    seq_along(images(.spd)), 
    \(i) asS3(plotImage(.spd, i=i))))

3.2 Rotation

# spin the raccoon (anti-clockwise)
.spd <- spd
images(.spd) <- lapply(
    c(0, 30, 60), 
    \(t) rotateElement(img, t))
wrap_plots(lapply(
    seq_along(images(.spd)), 
    \(i) asS3(plotImage(.spd, i=i))))

3.3 Scaling

# squeeze the raccoon horizontally
.spd <- spd
images(.spd) <- lapply(
    c(1, 2/3, 1/2),
    \(t) scaleElement(img, c(1, 1, t)))
wrap_plots(lapply(
    seq_along(images(.spd)), 
    \(i) asS3(plotImage(.spd, i=i))))

4 Visualization

4.1 By element

Element-wise plotting is possible via plotElement, which expects a single SpatialData element as input. Images and shapes are rendered via annotation_raster; for shapes (geom_polygon), additional graphical parameters may be passed as dot (...) arguments.

ps <- list(
    p1 <- plotImage(spd), 
    p2 <- plotLabel(spd, alpha=0.5), 
    p3 <- plotShape(spd, fill="grey"))
wrap_plots(lapply(ps, asS3))

4.2 Layered

The + operator allows overlaying arbitrary layers plotted with plotImage/Label/Shape/Point. Here, argument coord specifies the target coordinate system, and will default to the first shared one available if left unspecified. Elements are internally aligned via alignElements, which in turn calls transformArray on the input image and label (type Image/LabelArray). Depending on the underlying metadata, transformElement uses scale/rotate/translateElement for transformation.

p1 + p2 + p3

dir <- file.path("extdata", "blobs")
dir <- system.file(dir, package="SpatialData")
(spd <- readSpatialData(dir))
## class: SpatialData
## table: 3 10 
## images(2): blobs_image blobs_multiscale_image
## labels(2): blobs_labels blobs_multiscale_labels
## shapes(3): blobs_circles blobs_multipolygons blobs_polygons
## points(1): blobs_points
## coords(1): global
plotImage(spd) + 
    plotLabel(spd, alpha=0.5, fill="grey") + 
    plotShape(spd, i="blobs_polygons", fill=NA, col="white") + 
    plotPoint(spd, size=0.5, col="gold")

5 Query

5.1 Aggregation

aggregateImage computed aggregated measurement values from image according to label using fun to summarized measurements (default mean). By default, the first available image and label are used. In the output SingleCellExperiment, rows correspond to channels and columns to unique labels (excluding 0); aggregated xy-coordinates are included in the colData.

(sce <- aggregateImage(spd))
## class: SingleCellExperiment 
## dim: 3 10 
## metadata(0):
## assays(1): mean
## rownames: NULL
## rowData names(0):
## colnames(10): 3 4 ... 15 16
## colData names(2): x y
## reducedDimNames(0):
## mainExpName: NULL
## altExpNames(0):

6 Interoperability

6.1 MoleculeExperiment

library(MoleculeExperiment)
## Warning: package 'MoleculeExperiment' was built under R version 4.3.1
(me <- SpatialData2ME(spd, point="blobs_points", shape="blobs_polygons"))
## class:  MoleculeExperiment 
## 1 samples: sample1 
## 
## @molecules contents: 
## -detected assay:
## Location range across all samples in assay "detected": [10,53] x [10,53]
## 
## @boundaries contents:
## -detected:
## 5 unique segment IDs: 0 1 2 3 4 ...
ggplot_me() +
    geom_point_me(me, assayName="detected", byColour="feature_name", size=0.1) +
    geom_polygon_me(me, assayName="detected", byFill="segment_id", colour="black", alpha=0.1)

7 Platforms

7.1 MERFISH

devtools::load_all()
## ℹ Loading SpatialData
## Creating a new generic function for 'labels' in package 'SpatialData'
## 
## Creating a new generic function for 'table' in package 'SpatialData'
dir <- file.path("extdata", "merfish")
dir <- system.file(dir, package="SpatialData")
(spd <- readSpatialData(dir))
## class: SpatialData
## table: 268 2399 
## images(1): rasterized
## labels(0):
## shapes(2): anatomical cells
## points(1): single_molecule
## coords(1): global
(p <- point(spd))
## class: PointFrame
## length: 3714642 
## data(3): x y cell_type
## coords(1) : global
q <- p[sample(length(p), 1e3)]
.spd <- spd; point(.spd) <- q
p1 <- plotImage(.spd, width=400)
p2 <- plotShape(.spd, fill=NA, col="white")
p3 <- plotPoint(.spd, col="cell_type", size=0.5)
p1+p2+p3+
    theme(legend.key.size=unit(0.5, "lines")) +
    guides(col=guide_legend(override.aes=list(size=2)))

# filtering
plotPoint(.spd, x < 2e3, col="red") +
plotPoint(.spd, cell_type != "VISp_V", size=0.5, col="blue") +
plotPoint(.spd, cell_type == "outside_VISp", size=0.5, col="green") 

7.2 CosMx

devtools::load_all()
## ℹ Loading SpatialData
## Creating a new generic function for 'labels' in package 'SpatialData'
## 
## Creating a new generic function for 'table' in package 'SpatialData'
dir <- file.path("extdata", "cosmx_io")
dir <- system.file(dir, package="SpatialData")
(spd <- readSpatialData(dir))
## class: SpatialData
## table: 980 106660 
## images(30): 1_image 10_image ... 8_image 9_image
## labels(30): 1_labels 10_labels ... 8_labels 9_labels
## shapes(0):
## points(30): 1_points 10_points ... 8_points 9_points
## coords(1): global
plotImage(spd) + plotPoint(spd, CellComp == "Nuclear", col="white", alpha=0.1, size=0.01)

lapply(
    imageNames(spd)[seq(12)], 
    \(.) asS3(plotImage(spd, i=., width=100))) |>
    wrap_plots(nrow=3)

8 Appendix

8.1 Session info

sessionInfo()
## R version 4.3.0 (2023-04-21)
## Platform: aarch64-apple-darwin20 (64-bit)
## Running under: macOS Ventura 13.2.1
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
## LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## time zone: Europe/Brussels
## tzcode source: internal
## 
## attached base packages:
## [1] stats    graphics utils    stats4   methods  base    
## 
## other attached packages:
##  [1] SpatialData_0.99.0          testthat_3.1.10            
##  [3] MoleculeExperiment_1.1.2    SingleCellExperiment_1.23.0
##  [5] SummarizedExperiment_1.31.1 Biobase_2.61.0             
##  [7] GenomicRanges_1.53.1        GenomeInfoDb_1.37.4        
##  [9] IRanges_2.35.2              S4Vectors_0.39.1           
## [11] BiocGenerics_0.47.0         MatrixGenerics_1.13.1      
## [13] matrixStats_1.0.0           patchwork_1.1.3            
## [15] ggplot2_3.4.3               BiocStyle_2.29.2           
## 
## loaded via a namespace (and not attached):
##   [1] rstudioapi_0.15.0        jsonlite_1.8.7           magrittr_2.0.3          
##   [4] magick_2.7.5             farver_2.1.1             rmarkdown_2.24          
##   [7] fs_1.6.3                 zlibbioc_1.47.0          vctrs_0.6.3             
##  [10] memoise_2.0.1            RCurl_1.98-1.12          terra_1.7-46            
##  [13] usethis_2.2.2            htmltools_0.5.6          S4Arrays_1.1.6          
##  [16] curl_5.0.2               Rhdf5lib_1.23.2          SparseArray_1.1.12      
##  [19] rhdf5_2.45.1             sass_0.4.7               bslib_0.5.1             
##  [22] desc_1.4.2               htmlwidgets_1.6.2        basilisk_1.13.1         
##  [25] cachem_1.0.8             mime_0.12                lifecycle_1.0.3         
##  [28] pkgconfig_2.0.3          Matrix_1.6-1             R6_2.5.1                
##  [31] fastmap_1.1.1            GenomeInfoDbData_1.2.10  shiny_1.7.5             
##  [34] digest_0.6.33            colorspace_2.1-0         ps_1.7.5                
##  [37] paws.storage_0.4.0       rprojroot_2.0.3          pkgload_1.3.2.1         
##  [40] filelock_1.0.2           labeling_0.4.3           Rarr_1.1.2              
##  [43] fansi_1.0.4              httr_1.4.7               abind_1.4-5             
##  [46] compiler_4.3.0           remotes_2.4.2.1          bit64_4.0.5             
##  [49] withr_2.5.0              tiff_0.1-11              BiocParallel_1.35.4     
##  [52] pkgbuild_1.4.2           R.utils_2.12.2           sessioninfo_1.2.2       
##  [55] DelayedArray_0.27.10     rjson_0.2.21             tools_4.3.0             
##  [58] httpuv_1.6.11            R.oo_1.25.0              glue_1.6.2              
##  [61] callr_3.7.3              EBImage_4.43.0           rhdf5filters_1.13.5     
##  [64] promises_1.2.1           grid_4.3.0               generics_0.1.3          
##  [67] gtable_0.3.4             R.methodsS3_1.8.2        data.table_1.14.8       
##  [70] utf8_1.2.3               XVector_0.41.1           pillar_1.9.0            
##  [73] stringr_1.5.0            limma_3.57.7             later_1.3.1             
##  [76] dplyr_1.1.3              lattice_0.21-8           bit_4.0.5               
##  [79] tidyselect_1.2.0         paws.common_0.6.0        locfit_1.5-9.8          
##  [82] miniUI_0.1.1.1           knitr_1.44               bookdown_0.35           
##  [85] edgeR_3.43.8             xfun_0.40                datasets_4.3.0          
##  [88] statmod_1.5.0            brio_1.1.3               devtools_2.4.5          
##  [91] stringi_1.7.12           fftwtools_0.9-11         yaml_2.3.7              
##  [94] evaluate_0.21            codetools_0.2-19         tibble_3.2.1            
##  [97] BiocManager_1.30.22      cli_3.6.1                arrow_13.0.0            
## [100] xtable_1.8-4             reticulate_1.32.0        munsell_0.5.0           
## [103] processx_3.8.2           jquerylib_0.1.4          zellkonverter_1.11.2    
## [106] Rcpp_1.0.11              dir.expiry_1.9.0         png_0.1-8               
## [109] parallel_4.3.0           ellipsis_0.3.2           assertthat_0.2.1        
## [112] basilisk.utils_1.13.3    prettyunits_1.1.1        jpeg_0.1-10             
## [115] profvis_0.3.8            urlchecker_1.0.1         bitops_1.0-7            
## [118] SpatialExperiment_1.11.2 scales_1.2.1             grDevices_4.3.0         
## [121] purrr_1.0.2              crayon_1.5.2             rlang_1.1.1